Content Management Architecture
**Referenced Files in This Document** - [tina/config.ts](file://tina/config.ts) - [tina/__generated__/types.ts](file://tina/__generated__/types.ts) - [tina/__generated__/client.ts](file://tina/__generated__/client.ts) - [src/admin/config.yml](file://src/admin/config.yml) - [.eleventy.js](file://.eleventy.js) - [package.json](file://package.json) - [src/_data/site.json](file://src/_data/site.json) - [src/_data/testimonials.json](file://src/_data/testimonials.json) - [src/_data/capabilities.json](file://src/_data/capabilities.json) - [src/admin/index.html](file://src/admin/index.html) - [src/content/news/news.11tydata.json](file://src/content/news/news.11tydata.json) - [src/content/cases/cases.11tydata.json](file://src/content/cases/cases.11tydata.json) - [src/content/team/team.11tydata.json](file://src/content/team/team.11tydata.json) - [src/content/knowledge/knowledge.11tydata.js](file://src/content/knowledge/knowledge.11tydata.js)Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
Introduction
This document describes the content management architecture integrating TinaCMS with an Eleventy-powered static site. It covers the content schema with 10+ content types, generated TypeScript types, media management, preview and authentication flows, validation and sanitization, template rendering, and backup/export mechanisms.
Project Structure
The project is organized around:
- TinaCMS configuration and generated client/types
- Eleventy configuration and data collections
- Frontend templates and static assets
- Admin UI and CMS configuration
graph TB
subgraph "TinaCMS Layer"
CFG["tina/config.ts"]
GEN_TYPES["tina/__generated__/types.ts"]
GEN_CLIENT["tina/__generated__/client.ts"]
end
subgraph "Eleventy Layer"
ELEVENTY[".eleventy.js"]
DATA["_data/*.json"]
CONTENT["src/content/*"]
TINACMS_UI["src/admin/index.html"]
end
subgraph "Frontend"
TEMPLATES["_includes/*.njk"]
ASSETS["src/assets/*"]
end
CFG --> GEN_TYPES
CFG --> GEN_CLIENT
GEN_CLIENT --> TINACMS_UI
ELEVENTY --> DATA
ELEVENTY --> CONTENT
ELEVENTY --> TEMPLATES
TINACMS_UI --> TEMPLATES
ELEVENTY --> ASSETS
Diagram sources
- [tina/config.ts:1-331](file://tina/config.ts#L1-L331)
- [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
- [.eleventy.js:1-283](file://.eleventy.js#L1-L283)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
Section sources
- [tina/config.ts:1-331](file://tina/config.ts#L1-L331)
- [.eleventy.js:1-283](file://.eleventy.js#L1-L283)
- [package.json:1-32](file://package.json#L1-L32)
Core Components
- TinaCMS configuration defines collections for content types and data files, media roots, and build output.
- Generated TypeScript types provide strongly typed GraphQL queries and mutations for content types.
- Eleventy builds static pages from Markdown content and JSON data, exposing collections for templates.
- Admin UI integrates the TinaCMS client for editing.
Key responsibilities:
- Schema definition and media configuration in tina/config.ts
- Type-safe client usage via tina/generated/client.ts and types.ts
- Eleventy collections for rendering and permalinks
- Admin UI bootstrap and CMS integration
Section sources
- [tina/config.ts:1-331](file://tina/config.ts#L1-L331)
- [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
Architecture Overview
The CMS-to-rendering pipeline:
- TinaCMS schema drives content creation/editing and media storage.
- Generated types and client enable type-safe queries/mutations.
- Eleventy reads Markdown and JSON data to produce static HTML.
- Templates render content using Eleventy collections and computed permalinks.
sequenceDiagram
participant Editor as "Editor"
participant Admin as "Admin UI<br/>src/admin/index.html"
participant Tina as "Tina Client<br/>tina/__generated__/client.ts"
participant Types as "GraphQL Types<br/>tina/__generated__/types.ts"
participant Eleventy as "Eleventy Build<br/>.eleventy.js"
participant Site as "Static Site"
Editor->>Admin : Open CMS editor
Admin->>Tina : Initialize client
Tina->>Types : Use generated types for queries/mutations
Editor->>Tina : Save content changes
Tina-->>Eleventy : Persisted content (Markdown/JSON)
Eleventy->>Eleventy : Build collections and templates
Eleventy-->>Site : Emit static HTML/CSS/JS
Diagram sources
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
- [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
Detailed Component Analysis
Content Schema and Types
The schema defines 10+ content types across folder-based Markdown collections and data file collections. Each collection specifies fields, formats, and UI behavior.
Collections overview:
- Folder-based Markdown collections: news, cases, team, knowledge, newsletters
- Data file collections: settings, homepage, testimonials, clients, affiliations, partners, capabilities carousel, IAA partners, resources, and multiple service pages
Field types include strings, datetimes, booleans, numbers, images, rich-text, and lists of objects. UI hints indicate titles, body content, and formatting preferences.
Generated TypeScript types:
- Strongly typed queries and mutations for each content type
- Filters and connections for paginated retrieval
- Fragments for partial data fetching
classDiagram
class News {
+string title
+string date
+string author
+string excerpt
+string image
+string image_alt
+string pdf_url
+string pdf_label
+boolean featured
+boolean draft
+JSON body
}
class Cases {
+string client
+string category
+string title
+string image
+string image_alt
+string quote
+string quote_author
+number order
+boolean featured
+boolean draft
+JSON body
}
class Team {
+string anchor
+string name
+string role
+number order
+string image_index
+string image_profile
+string image_alt_index
+string image_alt_profile
+string bio_short
+boolean featured
+boolean draft
+JSON body
}
class Knowledge {
+string title
+string date
+string author
+string excerpt
+string[] tags_list
+JSON body
}
class Settings {
+string title
+string description
+string email
+string alliance_email
+string phone
+string address
+string abn
+number copyright_year
+string convertkit_form_id
+string web3forms_key
+string linkedin
}
class Homepage {
+string hero_title
+string hero_subtitle
+string hero_cta_text
+string hero_cta_url
+string capabilities_label
+string capabilities_heading
+string clients_label
+string testimonials_label
+string testimonials_heading
+string team_label
+string team_heading
+string news_label
+string news_heading
+string affiliations_label
+string affiliations_heading
+string cta_heading
+string cta_highlight
+string cta_sub
+string cta_btn_text
+string cta_btn_url
}
class Testimonials {
+object[] items
}
class Clients {
+object[] items
}
class Affiliations {
+object[] items
}
class Partners {
+object[] items
}
class CapCarousel {
+object[] items
}
class IaaPartners {
+object[] items
}
class Resources {
+object[] items
}
Diagram sources
- [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
- [tina/generated/types.ts:222-423](file://tina/generated/types.ts#L222-L423)
Section sources
- [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
- [tina/generated/types.ts:222-423](file://tina/generated/types.ts#L222-L423)
Generated TypeScript Types and Frontend Integration
The generated types provide:
- Typed query/mutation operations for each content type
- Filter types for querying subsets of content
- Connections and edges for pagination
- Fragments for efficient partial data loading
Integration with templates:
- Eleventy collections supply rendered content to Nunjucks templates
- Computed permalinks and metadata are available in templates
- Data files (JSON) are loaded via Eleventy’s data cascade
flowchart TD
Start(["Build"]) --> GenTypes["Generate GraphQL Types<br/>tina/__generated__/types.ts"]
GenTypes --> GenClient["Create Client<br/>tina/__generated__/client.ts"]
GenClient --> AdminUI["Admin UI Loads Client<br/>src/admin/index.html"]
AdminUI --> Edit["Editor Edits Content"]
Edit --> Persist["Persist to Markdown/JSON"]
Persist --> EleventyBuild["Eleventy Build<br/>.eleventy.js"]
EleventyBuild --> Render["Render Templates<br/>with Collections/Data"]
Render --> Output["Static Site Output"]
Diagram sources
- [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
Section sources
- [tina/generated/types.ts:1-800](file://tina/generated/types.ts#L1-L800)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
Relationship Between TinaCMS Collections and Eleventy Data Collections
- TinaCMS collections map to:
- Folder-based Markdown collections (news, cases, team, knowledge, newsletters)
- Data file collections (settings, homepage, testimonials, clients, affiliations, partners, capabilities carousel, IAA partners, resources, and service pages)
- Eleventy exposes collections for rendering:
- news, cases, newsletters, teamMembers, featuredNews, services, knowledge
- Permalink behavior:
- Some content disables permalinks (e.g., news, cases, team)
- Knowledge uses computed permalinks for member portal routing
graph LR
subgraph "TinaCMS Collections"
T_News["news"]
T_Cases["cases"]
T_Team["team"]
T_Knowledge["knowledge"]
T_Newsletters["newsletters"]
T_Settings["settings"]
T_Homepage["homepage"]
T_Testimonials["testimonials"]
T_Clients["clients"]
T_Affiliations["affiliations"]
T_Partners["partners"]
T_CapCarousel["capabilities carousel"]
T_Iaa["IAA partners"]
T_Resources["resources"]
end
subgraph "Eleventy Collections"
E_News["news"]
E_Cases["cases"]
E_Newsletters["newsletters"]
E_Team["teamMembers"]
E_Featured["featuredNews"]
E_Services["services"]
E_Knowledge["knowledge"]
end
T_News --> E_News
T_Cases --> E_Cases
T_Team --> E_Team
T_Knowledge --> E_Knowledge
T_Newsletters --> E_Newsletters
T_Settings --> E_News
T_Homepage --> E_News
T_Testimonials --> E_News
T_Clients --> E_News
T_Affiliations --> E_News
T_Partners --> E_News
T_CapCarousel --> E_News
T_Iaa --> E_News
T_Resources --> E_News
Diagram sources
- [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
- [src/content/news/news.11tydata.json:1-2](file://src/content/news/news.11tydata.json#L1-L2)
- [src/content/cases/cases.11tydata.json:1-2](file://src/content/cases/cases.11tydata.json#L1-L2)
- [src/content/team/team.11tydata.json:1-2](file://src/content/team/team.11tydata.json#L1-L2)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
Section sources
- [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
- [src/content/news/news.11tydata.json:1-2](file://src/content/news/news.11tydata.json#L1-L2)
- [src/content/cases/cases.11tydata.json:1-2](file://src/content/cases/cases.11tydata.json#L1-L2)
- [src/content/team/team.11tydata.json:1-2](file://src/content/team/team.11tydata.json#L1-L2)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
Media Management Architecture
- Media root configured under TinaCMS to store uploaded images.
- Public folder for media assets is served statically.
- Images are referenced by filename/path and used across content types and data files.
flowchart TD
Upload["Upload Image"] --> MediaRoot["Tina Media Root<br/>assets/repository/images/uploads"]
MediaRoot --> Publish["Publish Asset Path"]
Publish --> Content["Content Fields (image/image_alt)"]
Publish --> DataFiles["Data Files (logos/images)"]
Content --> Render["Template Rendering"]
DataFiles --> Render
Diagram sources
- [tina/config.ts:15-20](file://tina/config.ts#L15-L20)
- [src/_data/capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
- [src/_data/testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
Section sources
- [tina/config.ts:15-20](file://tina/config.ts#L15-L20)
- [src/_data/capabilities.json:1-53](file://src/_data/capabilities.json#L1-L53)
- [src/_data/testimonials.json:1-24](file://src/_data/testimonials.json#L1-L24)
Preview System and Live Changes
- Development script runs Eleventy in serve mode alongside TinaCMS dev server.
- The admin UI loads the Tina client and connects to the local GraphQL endpoint.
- Changes made in the CMS are persisted to Markdown/JSON and reprocessed by Eleventy.
sequenceDiagram
participant Dev as "Developer"
participant Scripts as "Scripts<br/>package.json"
participant Eleventy as "Eleventy Serve"
participant TinaDev as "Tina Dev Server"
participant Browser as "Browser"
Dev->>Scripts : npm run dev : cms
Scripts->>TinaDev : Start Tina dev server
Scripts->>Eleventy : Start Eleventy --serve
Browser->>TinaDev : Connect to CMS
Browser->>Eleventy : View live site updates
Diagram sources
- [package.json:5-12](file://package.json#L5-L12)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
Section sources
- [package.json:5-12](file://package.json#L5-L12)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
Authentication Flow and Member Portal Integration
- TinaCMS backend configured to GitHub for content storage.
- Admin UI bootstrapped via a minimal HTML entry point.
- Member portal content is managed via data files and service-specific collections, surfaced through Eleventy templates.
flowchart TD
Config["Tina Backend: GitHub<br/>src/admin/config.yml"] --> AdminUI["Admin UI<br/>src/admin/index.html"]
AdminUI --> Auth["Editor Login (GitHub)"]
Auth --> Edit["Edit Content"]
Edit --> Persist["Persist to Repo"]
Persist --> Build["Eleventy Build"]
Build --> MemberPortal["Member Portal Pages"]
Diagram sources
- [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
Section sources
- [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
- [src/admin/index.html:1-12](file://src/admin/index.html#L1-L12)
Content Validation and Sanitization
- Field-level validation is enforced by the schema (required fields, types).
- UI components (e.g., rich-text, markdown) guide content creation.
- Filtering and sorting are applied in Eleventy collections to surface validated content.
flowchart TD
Schema["Schema Fields<br/>tina/config.ts"] --> Validate["Validation Rules"]
Validate --> UI["UI Widgets<br/>src/admin/config.yml"]
UI --> Content["Persisted Content"]
Content --> Eleventy["Eleventy Collections<br/>.eleventy.js"]
Eleventy --> Render["Sanitized Rendering"]
Diagram sources
- [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
- [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
Section sources
- [tina/config.ts:22-329](file://tina/config.ts#L22-L329)
- [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
Relationship Between Content Models and Template Rendering
- Content models (news, cases, team, knowledge, newsletters) are rendered via Eleventy collections.
- Data models (settings, homepage, testimonials, clients, etc.) are loaded as JSON and injected into templates.
- Computed permalinks (e.g., knowledge) ensure consistent URLs for member portal routes.
graph TB
Models["Content Models<br/>Markdown + Front Matter"] --> Collections["Eleventy Collections<br/>.eleventy.js"]
Data["Data Models<br/>JSON Files"] --> EleventyData["Eleventy Data Cascade"]
Collections --> Templates["Nunjucks Templates"]
EleventyData --> Templates
Templates --> Output["Rendered Pages"]
Diagram sources
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
- [src/_data/site.json:1-20](file://src/_data/site.json#L1-L20)
Section sources
- [.eleventy.js:166-211](file://.eleventy.js#L166-L211)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
- [src/_data/site.json:1-20](file://src/_data/site.json#L1-L20)
Backup and Export Mechanisms
- Content is stored as Markdown and JSON files in the repository, enabling Git-based versioning and backups.
- TinaCMS GitHub backend ensures collaborative editing history and diffs.
- Build artifacts are static HTML/CSS/JS, suitable for deployment and archival.
Section sources
- [src/admin/config.yml:1-774](file://src/admin/config.yml#L1-L774)
- [package.json:5-12](file://package.json#L5-L12)
Dependency Analysis
- TinaCMS CLI and runtime depend on Node.js and Eleventy.
- Generated client depends on GraphQL types.
- Admin UI depends on the generated client.
- Eleventy depends on data files and content Markdown.
graph LR
Node["Node.js Runtime"] --> TinaCLI["@tinacms/cli"]
Node --> TinaRuntime["tinacms"]
TinaCLI --> TypesGen["Type Generation"]
TinaRuntime --> Client["Generated Client"]
Client --> Admin["Admin UI"]
Eleventy["@11ty/eleventy"] --> Site["_site Output"]
Admin --> Site
Diagram sources
- [package.json:14-30](file://package.json#L14-L30)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
Section sources
- [package.json:14-30](file://package.json#L14-L30)
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
Performance Considerations
- Keep media assets optimized; leverage the configured media root for centralized storage.
- Use Eleventy filters to limit and transform content efficiently.
- Prefer fragments and targeted queries to minimize payload sizes in the CMS.
Troubleshooting Guide
Common issues and resolutions:
- Client initialization errors: Verify the generated client URL and token configuration.
- Missing content in collections: Confirm file paths and front matter in Markdown files.
- Permalink mismatches: Review computed permalinks for knowledge and other dynamic routes.
- Build failures: Ensure scripts are executed in the correct order (Tina build before Eleventy).
Section sources
- [tina/generated/client.ts:1-5](file://tina/generated/client.ts#L1-L5)
- [src/content/knowledge/knowledge.11tydata.js:1-8](file://src/content/knowledge/knowledge.11tydata.js#L1-L8)
- [package.json:5-12](file://package.json#L5-L12)
Conclusion
The architecture combines TinaCMS for flexible content editing with Eleventy for robust static site generation. The schema supports diverse content types, while generated TypeScript types and a streamlined admin UI enable efficient authoring. Media, validation, and rendering are integrated to support both public and member portal experiences.
Appendices
- Environment variables used by TinaCMS: clientId, branch, token.
- Build and development scripts orchestrate TinaCMS and Eleventy.
Section sources
- [tina/config.ts:3-8](file://tina/config.ts#L3-L8)
- [package.json:5-12](file://package.json#L5-L12)